/* 
 *  Copyright (C) 2007 Dip. Ing. dell'Informazione, University of Pisa, Italy
 *  http://info.iet.unipi.it/~cng/ns2mesh80216/
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA, USA
 */

#include <math.h>

#include "mesh_phy.h"
#include "mesh_packet.h"
#include "mesh_channel.h"
#include "mesh_mac.h"
//#include <mesh_topology.h>

#define MAX(a,b) (((a)<(b))?(b):(a))
#define MIN(a,b) (((a)<(b))?(a):(b))

/*
 *
 * class MeshPhyMib
 *
 */

static class MeshPhyMibClass : public TclClass {
public:
   MeshPhyMibClass() : TclClass("MeshPhyMib") {}
   TclObject* create (int, const char*const*) {
      return (new MeshPhyMib () ) ;
   }
} class_Mesh_phy_mib;

// 字节
const unsigned int MeshPhyMib::alpha[]  = {
	24, 36, 48, 72, 96, 108 };


MeshPhyMib::MeshPhyMib ()
{
//	frameDuration_ = 0;
	symDuration_ = 0 ; 	// 2.0e-5 ;//会有误差
	symPerFrame_ = 500;
//	modulation_ = w_mesh::QPSK_1_2 ;
	modulation_ = w_mesh::QAM64_3_4;
	fbandwidth_ = 10.0;
	cfgInterval_ = 4;
	controlSlots_ = 4;
	frameDuration_ = 1.0e-2;		// symduration *symperframe
	g_ = 0.0625;
//	controlSlots_ = 0;
//	bind("modulation_",&modulation_);	tcltcl中不支持这种类型绑定，只能在com中设定了；
//	bind("fbandwidth_",&fbandwidth_);
//	bind("cfgInterval_",&cfgInterval_);
//	bind("controlSlots_",&controlSlots_);
//	bind("frameDuration_",&frameDuration_);
//	bind("g_",&g_);
	//UpdateFs (fs_);
	UpsymDuration ();
	bool flag_ = recompute();
	assert (  flag_);	// 没有使用？
		
	
//	bind( , );
	
}

int
MeshPhyMib::command (int argc, const char*const* argv)	// 变量尽量多用绑定，就可以在tcl里面少赋值了；
{
	if ( argc == 3 && strcmp (argv[1], "symDuration") == 0 ) {
		symDuration_ = 1.0e-6 * atof (argv[2]);  // in us
		return TCL_OK;
	} else if ( argc == 3 && strcmp (argv[1], "frameDuration") == 0 ) {
		frameDuration_ = 1.0e-3 * atof (argv[2]);
		return TCL_OK;
	} else if ( argc == 3 && strcmp (argv[1], "controlSlots") == 0 ) {
		controlSlots_ = (unsigned int) atoi (argv[2]);
		return TCL_OK;
	} else if ( argc == 3 && strcmp (argv[1], "cfg-interval") == 0 ) {
		cfgInterval_ = (unsigned int) atoi (argv[2]);
		return TCL_OK;
	} else if ( argc == 2 && strcmp (argv[1], "recompute") == 0 ) {
		if ( recompute() == true ) return TCL_OK;
		fprintf (stderr, "Invalid PHY parameters selection\n");
		return TCL_ERROR;
	} else if ( argc == 2 && strcmp (argv[1], "dump") == 0 ) {
		//dump (stderr);
		return TCL_OK;
	}
	return TCL_ERROR;
}

/* void
MeshPhyMib::dump (FILE* os)
{
	fprintf (os, "frame duration           = %f ms\n"
			       "OFDM symbol duration     = %f us\n"
					 "OFDM symbols per frame   = %d\n"
					 "OFDM symbols per slot    = %d\n"
					 "slots per frame          = %d\n"
					 "control slots per frame  = %d\n"
					 "MSH-NCFG frames interval = %d\n",
					 1.0e3 * frameDuration(),
					 1.0e6 * symDuration(),
					 symPerFrame(),
					 symPerSlot(),
					 slotPerFrame(),
					 controlSlots(),
					 cfgInterval());
} */

// 已知： frameDuration_ ， symDuration_，controlSlots_
// 求   ：symPerFrame_ ， symPerSlot_ ， slotPerFrame_
// 会产生误差；所以一个帧的minislot不是256，而是需要重新计算；！！！！！！！！！！！
bool
MeshPhyMib::recompute ()
{
	symPerFrame_ = (unsigned int) (frameDuration_ / symDuration_) ;
	if ( 7 * controlSlots_ > symPerFrame_ - 1 ) return false;
	symPerSlot_ = 1 + ( symPerFrame_ - 7 * controlSlots_ - 1 ) / 256;
	slotPerFrame_ = ( symPerFrame_ - 7 * controlSlots_ ) / symPerSlot_;
	if ( slotPerFrame_ == 0 ) return false;
	return true;
}

double
MeshPhyMib::nextFrame ()
{
	return frameDuration() * ceil ( NOW / frameDuration() );
}

/*
 *
 * class MeshPhy
 *
 */

static class MeshPhyClass : public TclClass {
public:
   MeshPhyClass() : TclClass("Phy/WirelessPhy/MeshPhy") {}
   TclObject* create(int, const char*const*) {
      return (new MeshPhy);
   }
} class_w_mesh_phy;

MeshPhy::MeshPhy () : rxFinishTimes_ (this)
{
	channel_ = 0;
	//phyMib_ = 0 ;
	epsilon_ = 5*1.0e-6;		//初始设定！
	nodeId_ = 99 ;
// 	bind ( , ）；
}

int
MeshPhy::command(int argc, const char*const* argv)//???有待改进
{
	if ( argc == 3 && strcmp (argv[1], "channel") == 0 ) {
		channel_ = (MeshChannel*) TclObject::lookup (argv[2]);
		downtarget_ = (NsObject*) channel_;
		return TCL_OK;
//	} else if ( argc == 3 && strcmp (argv[1], "phymib") == 0 ) {
//		phyMib_ = (MeshPhyMib*) TclObject::lookup (argv[2]);	//???有待改进
//		return TCL_OK;
//	} else if ( argc == 3 && strcmp (argv[1], "mac") == 0 ) {
//		mac_ = (MeshMac*) TclObject::lookup (argv[2]);
//		return TCL_OK;
	} else if ( argc == 3 && strcmp (argv[1], "epsilon") == 0 ) {
		epsilon_ = 1.0e-6 * atof (argv[2]);   // in us
		if ( epsilon_ < 0 ) {
			fprintf (stderr, "the epsilon value '%f' is not valid. "
					"Choose a positive (small) value\n", epsilon_);
			return TCL_ERROR;
		}
		return TCL_OK;
	}
	return WirelessPhy::command(argc,argv);
	
}


// 一般是由mac层调用，来设置的;//???有待改进 可否直接放回去phy层
// 主要是发送数据的时候，判断会不会对接受到的数据产生影响；可考虑在phy后到senddown的时候来判断；
// 从而不用在mac层考虑；
// phy层不设置状态！发送数据的时候，判断会不会对接受到的数据产生影响；在phy到senddown的时候来判断
/*
void
MeshPhy::setMode ( PhyStatus s )
{
	if ( W_MeshDebug::trace("WPHY::setMode") ) fprintf (stderr,
			"%.9f WPHY::setMode    [%d] phy %p channel %d mode %s\n",
			NOW, mac_->nodeId(), this, channel->uid(),
			( s == w_mesh::TX ) ? "TX" : ( s == w_mesh::RX ) ? "RX" : "NN");

	// if there are undispatched bursts to myself, we mark then as corrupted
	// in case we are switching from RX to TX or we are switching channel
	//
	// note that the descriptor is not removed from the list, since it
	// can still interfere with other bursts
	// 设置channel的时候，考虑那些突发是损坏的；

	if ( s_ == RX && s == TX ) ) {
		std::list<Packet>::iterator it;
		for ( it = rxPacket_.begin() ; it != rxPacket_.end() ; it++ ) {
			hdr_cmn *cmn = HDR_CMN(it);
			if ( gt (it->finish_, NOW) && it->burst_ != 0 ) {
				it->error () = true;
			}
		}
	}

	s_ = s;
}

*/
void
MeshPhy::handle (Packet* p)
{



	


	// if there is no packet into the earliest element, just ignore it
	if ( p == 0 ) return;

	if (HDR_CMN(p)->direction() ==hdr_cmn::DOWN ) printf( "phy 收到方向错误的packet！ 239");


/*//test

			 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);		// 3.11
	 			MeshBurst*  burst = hdr_m->burst_ ;
	 			burst->free();	
				Packet::free (p);	
				return;

//test 
*/
	// otherwise, check whether this packet can be received

	// first, find the element with that burst into the list
	std::list<recvPacket>::iterator cur;
	for ( cur = rxPacket_.begin();cur != rxPacket_.end() ; ++cur ) {
		
		if( (*cur).pkt_ == p ) break;
	}
	
	if ( cur == rxPacket_.end() ) printf ("phy 259 出错！");

	assert ( cur != rxPacket_.end() );

	// then, check all the elements into the rx lists

	hdr_cmn *cmn = HDR_CMN((*cur).pkt_);
	hdr_meshmac *myhdr_ = HDR_MESHMAC((*cur).pkt_);

	if(cmn->error() == 0 ) {
	
	std::list<recvPacket>::iterator it;
	for ( it = rxPacket_.begin() ; it != rxPacket_.end() ; ++it ) {

//		hdr_cmn *cmn = HDR_CMN((*it).pkt_);		// packet 头是独立的
		hdr_meshmac *hdr_ = HDR_MESHMAC((*it).pkt_);	// 这个mesh头不是独立的

		// skip the burst itself
		if ( it == cur ) continue;

		// check if the channels interfere 有待添加mesh包头，有待修改；
//		if ( hdr_->channel_ != myhdr_->channel_ )
//			continue;

		// check if the transmission times overlap	有待添加：
		if ( ! ( gt ((*it).finish_, (*cur).start_) &&
					gt ((*cur).finish_, (*it).start_ ) ) ) {
			
			continue;
		}else {
//			 printf("gt 出错 , \n");
		}


		// if we are here, then the current transmission collides
//		cmn->error() = true;
		break;
	}

	}	// end if
	
	
	

	// send the burst to the MAC layer
	// mac_->recvBurst (cur->burst_);
	//cur->burst_ = 0;

	// 以为要考虑gt，即相互间是否会冲突，所以即使发生错误的packet也不能free
	// 所有的packet是否free都通过下面的语句判断；
	// check if there are elements in the list that can be removed
	// 1. find the latest undispatched start time
	// 2. remove all elements that have been dispatched before that time
	
	// 这个算法有问题；lateststart 应该是求出没有结束的最早的packet；
/*
	double latestStart = -1;
	for ( it = rxBursts_.begin() ; it != rxBursts_.end() ; ++it ) {
		if ( ! gt (NOW, it->finish_) )   // undispatched； 其结束时间是大于now的
			if ( latestStart < 0 || it->start_ > latestStart)
				latestStart = it->start_;

	}
	
	if ( latestStart < 0 ) {  // ie. no undispatched elements
		rxBursts_.clear ();
	} else {
		for ( it = rxBursts_.begin() ; it != rxBursts_.end() ; ) {
			if ( it->finish_ < latestStart ) {
				std::list<BurstDesc>::iterator drop = it;
				++it;
				rxBursts_.erase (drop);
			} else {
				++it;
			}
		}
	}	*/

/////////////////////////////////////////////////////////////////////////////////

	std::list<W_MeshPdu*>::iterator pt_;
 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);		// 3.11
	MeshBurst*  burst = hdr_m->burst_ ;


	for (pt_ = burst->pdus().begin() ; pt_ !=burst->pdus().end(); pt_++) {
			
			W_MeshPdu* pdu ;
			pdu = *pt_;

			if( HDR_CMN(pdu->sdu()->ip())->uid()== 2667  ) {
				printf( "节点 %d的PHY 准备把 uid 为 2667 的packet发送到上层MAC ， %d \n",nodeId_, cmn->error() );
			}
	}

///////////////////////////////////////////////////////////////////////////////////////////////

	// 把recv函数放在最后，是为了防止在判断之前，上层就把正确的packet free掉；	// 3.24
	if ( cmn->error() == 0)
		uptarget_->recv(p, (Handler*) 0);


//			 	hdr_meshmac *hdr_mesh = HDR_MESHMAC(p);		// 3.11
//	 			MeshBurst*  burst_ = hdr_mesh->burst_ ;
//	 			burst_->free();	
//				Packet::free (p);
//	return;

//////////////////////////////////////////////////////////////////////////////////////////////
// 有待完善： free 错误的 packet

	double latestStart = -1;
	std::list<recvPacket>::iterator it;
	for ( it =rxPacket_.begin() ; it != rxPacket_.end() ; ++it) {

		//hdr_meshmac *hdr_ = HDR_MESHMAC(*it);
		
		if ( ! gt (NOW , (*it).finish_ ) )		// 还没发送完成的
			if ( latestStart < 0 || (*it).start_ < latestStart )
				latestStart = (*it).start_;
	}

	if ( latestStart < 0 ) {
		
		for ( it =rxPacket_.begin() ; it != rxPacket_.end() ; ++it) {
//			hdr_cmn *hdr = HDR_CMN(*it);
//			if(hdr->error() == 1) {
			 	hdr_meshmac *hdr_m = HDR_MESHMAC((*it).pkt_);		// 3.11
	 			MeshBurst*  burst = hdr_m->burst_ ;
	 			burst->free();	
				Packet::free ((*it).pkt_);

				//Packet::del() ; 	//3.27	
//			}
		}
					
		rxPacket_.clear ();
	} else {
		for ( it = rxPacket_.begin() ; it != rxPacket_.end() ; ) {
			
//			hdr_meshmac *hdr_ = HDR_MESHMAC(*it);
	
			if ( (*it).finish_ < latestStart ) {				

				std::list<recvPacket>::iterator drop = it;
				++it;
//				hdr_cmn *hdr = HDR_CMN( (*drop).pkt_ );
//				if(hdr->error() == 1) {
				 	hdr_meshmac *hdr_m = HDR_MESHMAC((*drop).pkt_);		// 3.11
		 			MeshBurst*  burst = hdr_m->burst_ ;
		 			burst->free();	
					Packet::free ( (*drop).pkt_ );	

					//Packet::del() ;   // 3.27
//				}
				rxPacket_.erase (drop);
			} else {
				++it;
			}
		}
	}	
	
//	rxPacket_.swap(rxPacket_);		// by lhz 3.31
//	if ( cmn->error() == 1) { 

		//printf(  "%d物理层收到 %d 发来的 错误的包\n", nodeId_,myhdr_->burst_->source () );
//	 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);		// 3.11
//		MeshBurst*  burst = hdr_m->burst_ ;
//		burst->free();	
//		Packet::free (p);	
//	}


}



void MeshPhy::sendDown(Packet *p)
{




//	hdr_mac802_16* wph = HDR_MAC802_16(p);
//	hdr_cmn *ch = HDR_CMN(p);

//	int burstsize_ = ch-> size_ ;

//	w_mesh::BurstProfile mod = phyMib_->GetModulation ();
	
//	ch->txtime_ = phyMib_-> GetTrxTime (burstsize_ , mod);	
//传输时间的计算，放在了mac层
	std::list<recvPacket>::iterator it;

	// 发送数据的时候，此时收到的数据可能会发生冲突;
	for ( it = rxPacket_.begin() ; it != rxPacket_.end() ; it++ ) {
			

			hdr_cmn *cmn = HDR_CMN((*it).pkt_);
			hdr_meshmac *hdr_ = HDR_MESHMAC( (*it).pkt_);
			if ( gt ((*it).finish_, NOW) && hdr_->burst_ != 0 ) {
				cmn->error () = true;
			}
		
	}
	
	
	
	//the packet can be sent
//	WirelessPhy::sendDown (p);

////////////////////////////////////////////////
	/*
	 * Sanity Check
	 */
	assert(initialized());
	
	if (em()) {
			//node is off here...
			if (Is_node_on() != true ) {

		 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);		// 3.11
	 		MeshBurst*  burst = hdr_m->burst_ ;
	 		burst->free();
	
			Packet::free(p);
			printf( "em free phy.cc:459");
			return;
			}
			if(Is_node_on() == true && Is_sleeping() == true){
			em()-> DecrSleepEnergy(NOW-update_energy_time_,
							P_sleep_);
			update_energy_time_ = NOW;

			}

	}
	/*
	 * Decrease node's energy
	 */
	if(em()) {
		if (em()->energy() > 0) {

		    double txtime = hdr_cmn::access(p)->txtime();
		    double start_time = MAX(channel_idle_time_, NOW);
		    double end_time = MAX(channel_idle_time_, NOW+txtime);
		    double actual_txtime = end_time-start_time;

		    if (start_time > update_energy_time_) {
			    em()->DecrIdleEnergy(start_time - 
						 update_energy_time_, P_idle_);
			    update_energy_time_ = start_time;
		    }

		    /* It turns out that MAC sends packet even though, it's
		       receiving some packets.
		    
		    if (txtime-actual_txtime > 0.000001) {
			    fprintf(stderr,"Something may be wrong at MAC\n");
			    fprintf(stderr,"act_tx = %lf, tx = %lf\n", actual_txtime, txtime);
		    }
		    */

		   // Sanity check
		   double temp = MAX(NOW,last_send_time_);

		   /*
		   if (NOW < last_send_time_) {
			   fprintf(stderr,"Argggg !! Overlapping transmission. NOW %lf last %lf temp %lf\n", NOW, last_send_time_, temp);
		   }
		   */
		   
		   double begin_adjust_time = MIN(channel_idle_time_, temp);
		   double finish_adjust_time = MIN(channel_idle_time_, NOW+txtime);
		   double gap_adjust_time = finish_adjust_time - begin_adjust_time;
		   if (gap_adjust_time < 0.0) {
			   fprintf(stderr,"What the heck ! negative gap time.\n");
		   }

		   if ((gap_adjust_time > 0.0) && (status_ == RECV)) {
			   em()->DecrTxEnergy(gap_adjust_time,
					      Pt_consume_-Pr_consume_);
		   }

		   em()->DecrTxEnergy(actual_txtime,Pt_consume_);
//		   if (end_time > channel_idle_time_) {
//			   status_ = SEND;
//		   }
//
		   status_ = IDLE;

		   last_send_time_ = NOW+txtime;
		   channel_idle_time_ = end_time;
		   update_energy_time_ = end_time;

		   if (em()->energy() <= 0) {
			   em()->setenergy(0);
			   ((MobileNode*)node())->log_energy(0);
		   }

		} else {

			// log node energy
			if (em()->energy() > 0) {
				((MobileNode *)node_)->log_energy(1);
			} 
//

		 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);		// 3.11
	 		MeshBurst*  burst = hdr_m->burst_ ;
	 		burst->free();

			Packet::free(p);
			printf( "em free phy.cc:546");
			return;
		}
	}

	/*
	 *  Stamp the packet with the interface arguments
	 */
	p->txinfo_.stamp((MobileNode*)node(), ant_->copy(), Pt_, lambda_);
	
////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

	std::list<W_MeshPdu*>::iterator pt_;
 	hdr_meshmac *hdr_m = HDR_MESHMAC(p);
//	hdr_cmn *cmn = HDR_CMN(p);	// 3.11
	MeshBurst*  burst = hdr_m->burst_ ;
	

	for (pt_ = burst->pdus().begin() ; pt_ !=burst->pdus().end(); pt_++) {
			
			W_MeshPdu* pdu ;
			pdu = *pt_;

			if( HDR_CMN(pdu->sdu()->ip())->uid()== 2667  ) {
				printf( "节点 %d的PHY 准备把 uid 为 2667 的packet发送到channel  \n",nodeId_ );
			}
	}
/////////////////////////////////////////////////////////////////


	// Send the packet
	channel_->recv(p, this);

////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

int MeshPhy::sendUp(Packet *p)
{	
	hdr_cmn *cmn = HDR_CMN(p);
	recvPacket recPkt_;
	recPkt_.start_ = NOW;
	recPkt_.finish_= NOW + cmn->txtime_;
	recPkt_.pkt_ = p;	
	rxPacket_.push_back (recPkt_);
	
	// set the timer to the nearest finish time event
//	rxFinishTimes_.add (ch->txtime_, p);

	
	

	return WirelessPhy::sendUp (p);
}

//计算给定的调制方式下发送给定长数据（以字节为单位）所需的时间
double MeshPhyMib::GetTrxTime (int burstsize, w_mesh::BurstProfile mod) {
	//we compute the number of symbols required
	
	int bytes;

	switch (mod) {
	case w_mesh::QPSK_1_2:
		bytes = alpha[0];
		break;
	case w_mesh::QPSK_3_4:
		bytes = alpha[1];
		break;
	case w_mesh::QAM16_1_2:
		bytes = alpha[2];
		break;
	case w_mesh::QAM16_3_4:
		bytes = alpha[3];
		break;
	case w_mesh::QAM64_2_3:
		bytes = alpha[4];
		break;
	case w_mesh::QAM64_3_4:
		bytes = alpha[5];
		break;
	default:
		printf ("Error: unknown modulation: method getTrxTime in file ofdmphy.cc\n");
		
		exit (1);
	}
	// +2 表示每个突发都是用长前导：两个ofdm符号
	// 在phy层向channel传的packet，实际上就是burst；
	return  symDuration() * ( 1 + 2 + ( burstsize -1 ) / bytes ) ;

}


//设置调制方式
void  MeshPhyMib::SetModulation (w_mesh::BurstProfile modulation ) {
	modulation_ = modulation;
}

//查看调制方式
w_mesh::BurstProfile MeshPhyMib::GetModulation () {
	return modulation_;
}


// 更新采样频率：
//void MeshPhyMib::UpdateFs (double& fs_) {
  /* Fs=floor (n.BW/8000)*8000
   * and n=8/7 is channel bandwidth multiple of 1.75Mhz
   * n=86/75 is channel bandwidth multiple of 1.5Mhz
   * n=144/125 is channel bandwidth multiple of 1.25Mhz
   * n=316/275 is channel bandwidth multiple of 2.75Mhz
   * n=57/50 is channel bandwidth multiple of 2.0Mhz
   * n=8/7 for all other cases
   	*/
/*	double n; 

	if (((int) (fbandwidth_ / 1.75)) * 1.75 == fbandwidth_) {
		n = 8.0/7;
	} else if (((int) (fbandwidth_ / 1.5)) * 1.5 == fbandwidth_) {
		n = 86.0/75;
	} else if (((int) (fbandwidth_ / 1.25)) * 1.25 == fbandwidth_) {
		n = 144.0/125;
	} else if (((int) (fbandwidth_ / 2.75)) * 2.75 == fbandwidth_) {
		n = 316.0/275;
	} else if (((int) (fbandwidth_ / 2.0)) * 2.0 == fbandwidth_) {
		n = 57.0/50;
	} else {
		n = 8.0/7;
	}
	
	fs_ = floor (n*fbandwidth_/8000) * 8000;//基本上来说采样频率就是8M
}
*/

void MeshPhyMib::UpsymDuration () {

	double n; 

	fs_ = 1.0;
	if (((int) (fbandwidth_ / 1.75)) * 1.75 == fbandwidth_) {
		n = 8.0/7;
	} else if (((int) (fbandwidth_ / 1.5)) * 1.5 == fbandwidth_) {
		n = 86.0/75;
	} else if (((int) (fbandwidth_ / 1.25)) * 1.25 == fbandwidth_) {
		n = 144.0/125;
	} else if (((int) (fbandwidth_ / 2.75)) * 2.75 == fbandwidth_) {
		n = 316.0/275;
	} else if (((int) (fbandwidth_ / 2.0)) * 2.0 == fbandwidth_) {
		n = 57.0/50;
	} else {
		n = 8.0/7;
	}
	
	fs_ =  floor( (n*fbandwidth_*1.0e+6/8000))*8000;  //基本上来说采样频率就是8M

//	printf("fs_ is %d and n is %f , fbandwidth_ is %d\n" ,fs_,n,fbandwidth_);
	symDuration_ =(  (1 + g_ ) *  (double)256 ) / fs_  ;  /// s为单位；
}


void
MeshPhy::recv(Packet* p, Handler*)
{


					
	struct hdr_cmn *ch = HDR_CMN(p);
	struct hdr_meshmac *meshmac=HDR_MESHMAC(p);	
	//struct hdr_sr *hsr = HDR_SR(p);
	
	/*
	 * Handle outgoing packets
	 */
	int good_;
	switch(ch->direction()) {
	case hdr_cmn::DOWN :
		/*
		 * The MAC schedules its own EOT event so we just
		 * ignore the handler here.  It's only purpose
		 * it distinguishing between incoming and outgoing
		 * packets.
		 */
			
		nodeId_ = meshmac->burst_->source();




		sendDown(p);
		return;
	case hdr_cmn::UP :
		

//		 meshmac->burst_->free();	
//		 Packet::free(p);
//		 break;

	
		//if ( nodeId_ != meshmac->burst_->source()) {
		
		good_ = sendUp (p);

		if ( ! good_ ) {
			ch->error() = 1; 
		}
		  
//		meshmac->burst_->free();	
//	 	Packet::free(p);
		rxFinishTimes_.add (ch->txtime_, p);
		
			//uptarget_->recv(p, (Handler*) 0);
		//}
		
		break;
	default:



		
		//if ( nodeId_ != meshmac->burst_->source() ) {

		good_ = sendUp (p);

		if ( ! good_ ) {
			ch->error() = 1; 
		}

//		meshmac->burst_->free();	
//	 	Packet::free(p);
//		break;
		rxFinishTimes_.add (ch->txtime_, p);
		//}		
		break;
	}
	
}

